package com.example.mycontroller

import android.os.Bundle
import androidx.fragment.app.FragmentActivity
import androidx.activity.enableEdgeToEdge
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.example.mycontroller.ui.theme.MyControllerTheme
import android.widget.Toast
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.IOException
import android.content.Context
import android.graphics.BitmapFactory
import android.widget.EditText
import android.widget.Button
import android.widget.ImageView
import android.widget.Spinner
import android.widget.Switch
import android.widget.TimePicker
import android.widget.AdapterView
import android.widget.ArrayAdapter
import java.net.Socket
import java.nio.ByteBuffer
import android.view.View
import java.net.SocketTimeoutException
import java.net.ConnectException
import java.nio.ByteOrder
import android.view.ScaleGestureDetector
import android.view.ViewGroup
import android.widget.ScrollView
import android.view.MotionEvent
import android.util.Log
import androidx.biometric.BiometricPrompt
import androidx.core.content.ContextCompat
import android.content.Intent
import android.provider.Settings

class MainActivity : FragmentActivity() {
    private lateinit var serverIpEditText: EditText
    private lateinit var serverPortEditText: EditText
    private lateinit var lockButton: Button
    private lateinit var unlockButton: Button
    private lateinit var shutdownButton: Button
    private lateinit var snapshotButton: Button
    private lateinit var snapshotImageView: ImageView
    private lateinit var serverIpSpinner: Spinner
    private lateinit var shutdownSwitch: Switch
    private lateinit var shutdownTimePicker: TimePicker
    private lateinit var spinnerAdapter: ArrayAdapter<String>

    private val recentIpAddresses = mutableListOf<String>()
    private val PREF_NAME = "LockDesktopPref"
    private val IP_ADDRESSES_KEY = "RecentIpAddresses"

    private var isImageFullscreen = false
    private var originalHeight = 0
    private lateinit var scaleGestureDetector: ScaleGestureDetector
    private var scaleFactor = 1.0f

    private lateinit var biometricPrompt: BiometricPrompt
    private lateinit var promptInfo: BiometricPrompt.PromptInfo

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setupBiometricAuth()

        // 将原有的初始化代码移到认证成功的回调中
        biometricPrompt.authenticate(promptInfo)
    }

    private fun initializeViews() {
        serverIpEditText = findViewById(R.id.serverIpEditText)
        serverPortEditText = findViewById(R.id.serverPortEditText)
        lockButton = findViewById(R.id.lockButton)
        unlockButton = findViewById(R.id.unlockButton)
        shutdownButton = findViewById(R.id.shutdownButton)
        snapshotButton = findViewById(R.id.snapshotButton)
        snapshotImageView = findViewById(R.id.snapshotImageView)
        serverIpSpinner = findViewById(R.id.serverIpSpinner)
        shutdownSwitch = findViewById(R.id.shutdownSwitch)
        shutdownTimePicker = findViewById(R.id.shutdownTimePicker)
    }

    private fun initializeAdapter() {
        spinnerAdapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, recentIpAddresses)
        spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
        serverIpSpinner.adapter = spinnerAdapter
    }

    private fun setupListeners() {
        lockButton.setOnClickListener { sendCommandToServer("lock") }
        unlockButton.setOnClickListener { sendCommandToServer("unlock") }
        shutdownButton.setOnClickListener { sendCommandToServer("shutdown") }
        snapshotButton.setOnClickListener { sendCommandToServer("snapshot") }

        serverIpSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
                serverIpEditText.setText(recentIpAddresses[position])
            }
            override fun onNothingSelected(parent: AdapterView<*>?) {}
        }

        shutdownSwitch.setOnCheckedChangeListener { _, isChecked ->
            shutdownTimePicker.isEnabled = isChecked
            val hour = shutdownTimePicker.hour
            val minute = shutdownTimePicker.minute
            val time = String.format("%02d:%02d:00", hour, minute)
            val command = "shutdownplan_${isChecked}_$time"

            // 添加日志输出
            Log.d("ShutdownPlan", "Sending command: $command")
            showToastOnMainThread("发送命令: $command")

            sendCommandToServer(command)
        }

        shutdownTimePicker.setOnTimeChangedListener { _, hour, minute ->
            if (shutdownSwitch.isChecked) {
                val time = String.format("%02d:%02d:00", hour, minute)
                val command = "shutdownplan_${shutdownSwitch.isChecked}_$time"

                // 添加日志输出
                Log.d("ShutdownPlan", "Time changed, sending command: $command")
                showToastOnMainThread("发送命令: $command")

                sendCommandToServer(command)
            }
        }
    }

    private fun loadIpAddresses() {
        val prefs = getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
        val storedIps = prefs.getString(IP_ADDRESSES_KEY, "")
        if (!storedIps.isNullOrEmpty()) {
            recentIpAddresses.addAll(storedIps.split(","))
            spinnerAdapter.notifyDataSetChanged()
        }
    }

    private fun saveIpAddresses() {
        val prefs = getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE).edit()
        prefs.putString(IP_ADDRESSES_KEY, recentIpAddresses.joinToString(","))
        prefs.apply()
    }

    private fun addIpAddress(ipAddress: String) {
        recentIpAddresses.remove(ipAddress)
        recentIpAddresses.add(0, ipAddress)
        if (recentIpAddresses.size > 5) {
            recentIpAddresses.removeAt(5)
        }
        saveIpAddresses()
        spinnerAdapter.notifyDataSetChanged()
    }

    private fun sendCommandToServer(command: String) {
        lifecycleScope.launch(Dispatchers.IO) {
            try {
                val serverIp = serverIpEditText.text.toString()
                val serverPortText = serverPortEditText.text.toString()

                if (serverIp.isEmpty() || serverPortText.isEmpty()) {
                    showToast("请输入有效的服务器IP和端口")
                    return@launch
                }

                // 检查IP地址格式
                if (serverIp == "127.0.0.1" || serverIp == "localhost") {
                    showToast("请使用PC的实际IP地址，而不是127.0.0.1或localhost")
                    return@launch
                }

                val serverPort = serverPortText.toIntOrNull()
                if (serverPort == null) {
                    showToast("端口必须是数字")
                    return@launch
                }

                withContext(Dispatchers.Main) {
                    showToast("正在连接到 $serverIp:$serverPort ...")
                }

                Socket(serverIp, serverPort).use { socket ->
                    socket.soTimeout = 10000 // 增加超时时间到10秒

                    val outputStream = socket.getOutputStream()
                    outputStream.write(command.toByteArray())
                    outputStream.flush()

                    if (command == "snapshot") {
                        val inputStream = socket.getInputStream()

                        // 读取图像长度（4字节）
                        val lengthBytes = ByteArray(4)
                        var bytesRead = 0
                        var totalBytesRead = 0

                        while (totalBytesRead < 4) {
                            bytesRead = inputStream.read(lengthBytes, totalBytesRead, 4 - totalBytesRead)
                            if (bytesRead == -1) {
                                throw IOException("连接在读取图像大小时关闭")
                            }
                            totalBytesRead += bytesRead
                        }

                        val imageLength = ByteBuffer.wrap(lengthBytes).order(ByteOrder.LITTLE_ENDIAN).int

                        // 验证图像大小是否合理
                        if (imageLength <= 0 || imageLength > 50 * 1024 * 1024) { // 最大50MB
                            throw IOException("无效的图像大小: $imageLength bytes")
                        }

                        showToast("正在接收图像数据 ($imageLength bytes)...")

                        // 读取图像数据
                        val imageBytes = ByteArray(imageLength)
                        totalBytesRead = 0

                        while (totalBytesRead < imageLength) {
                            bytesRead = inputStream.read(imageBytes, totalBytesRead, imageLength - totalBytesRead)
                            if (bytesRead == -1) {
                                throw IOException("连接在读取图像数据时关闭")
                            }
                            totalBytesRead += bytesRead

                            // 更新进度
                            val progress = (totalBytesRead.toFloat() / imageLength * 100).toInt()
                            if (progress % 10 == 0) {
                                showToast("接收进度: $progress%")
                            }
                        }

                        // 在接收到图片数据后的处理
                        val bitmap = BitmapFactory.decodeByteArray(imageBytes, 0, imageLength)
                        if (bitmap == null) {
                            throw IOException("无法解码图像数据")
                        }
                        updateSnapshotImage(bitmap)

                        addIpAddress(serverIp)
                    }
                }
            } catch (e: SocketTimeoutException) {
                showToast("连接超时：请检查网络连接")
            } catch (e: ConnectException) {
                showToast("连接失败：请确保服务器正在运行")
            } catch (e: IOException) {
                showToast("IO错误: ${e.message}")
            } catch (e: Exception) {
                showToast("错误: ${e.message}")
                e.printStackTrace()
            }
        }
    }

    // 用于在主线程显示 Toast 的方法
    private suspend fun showToast(message: String) {
        withContext(Dispatchers.Main) {
            Toast.makeText(this@MainActivity, message, Toast.LENGTH_SHORT).show()
        }
    }

    // 添加一个非挂起函数版本，用于在非协程上下文中调用
    private fun showToastOnMainThread(message: String) {
        lifecycleScope.launch(Dispatchers.Main) {
            Toast.makeText(this@MainActivity, message, Toast.LENGTH_SHORT).show()
        }
    }

    private fun setupImageInteraction() {
        // 初始化缩放检测器，使用新的构建器模式
        scaleGestureDetector = ScaleGestureDetector(
            this,
            ScaleListener()
        ).apply {
            isQuickScaleEnabled = false // 禁用快速缩放
        }

        // 设置图片可点击和可触摸
        snapshotImageView.apply {
            isClickable = true
            isFocusable = true
            // 启用触摸事件的拦截
            isEnabled = true
        }

        var touchCount = 0
        var lastTouchTime = 0L
        var startX = 0f
        var startY = 0f
        val CLICK_TIME_THRESHOLD = 300L
        val CLICK_DISTANCE_THRESHOLD = 20f

        snapshotImageView.setOnTouchListener { view, event ->
            when (event.actionMasked) {
                MotionEvent.ACTION_DOWN -> {
                    touchCount = 1
                    lastTouchTime = System.currentTimeMillis()
                    startX = event.x
                    startY = event.y
                    // 确保父视图不拦截触摸事件
                    view.parent?.requestDisallowInterceptTouchEvent(true)
                }
                MotionEvent.ACTION_POINTER_DOWN -> {
                    touchCount++
                    // 当有多个手指时，确保父视图不拦截触摸事件
                    view.parent?.requestDisallowInterceptTouchEvent(true)
                }
                MotionEvent.ACTION_MOVE -> {
                    // 如果是多点触摸或在全屏模式下，阻止父视图拦截
                    if (touchCount >= 2 || isImageFullscreen) {
                        view.parent?.requestDisallowInterceptTouchEvent(true)
                    }
                }
                MotionEvent.ACTION_UP -> {
                    if (touchCount == 1 &&
                        (System.currentTimeMillis() - lastTouchTime) < CLICK_TIME_THRESHOLD &&
                        Math.abs(event.x - startX) < CLICK_DISTANCE_THRESHOLD &&
                        Math.abs(event.y - startY) < CLICK_DISTANCE_THRESHOLD
                    ) {
                        view.performClick()
                        toggleImageFullscreen()
                    }
                    touchCount = 0
                    // 释放触摸事件拦截
                    view.parent?.requestDisallowInterceptTouchEvent(false)
                }
                MotionEvent.ACTION_POINTER_UP -> {
                    touchCount--
                }
                MotionEvent.ACTION_CANCEL -> {
                    touchCount = 0
                    view.parent?.requestDisallowInterceptTouchEvent(false)
                }
            }

            // 总是处理缩放手势
            if (touchCount >= 2) {
                scaleGestureDetector.onTouchEvent(event)
            }

            true
        }

        // 保存原始高度
        snapshotImageView.post {
            originalHeight = snapshotImageView.height
        }
    }

    private inner class ScaleListener : ScaleGestureDetector.SimpleOnScaleGestureListener() {
        override fun onScaleBegin(detector: ScaleGestureDetector): Boolean {
            return true // 返回 true 表示我们要处理这个缩放手势
        }

        override fun onScale(detector: ScaleGestureDetector): Boolean {
            if (isImageFullscreen) {
                // 计算新的缩放因子
                scaleFactor *= detector.scaleFactor

                // 限制缩放范围
                scaleFactor = scaleFactor.coerceIn(0.5f, 5.0f)

                // 在主线程中更新 UI
                snapshotImageView.post {
                    snapshotImageView.scaleX = scaleFactor
                    snapshotImageView.scaleY = scaleFactor
                }

                return true
            }
            return false
        }

        override fun onScaleEnd(detector: ScaleGestureDetector) {
            // 缩放结束时的处理（如果需要）
        }
    }

    private fun toggleImageFullscreen() {
        isImageFullscreen = !isImageFullscreen

        val params = snapshotImageView.layoutParams
        if (isImageFullscreen) {
            params.height = ViewGroup.LayoutParams.MATCH_PARENT
            snapshotImageView.scaleType = ImageView.ScaleType.FIT_CENTER
            findViewById<ScrollView>(R.id.controlScrollView).visibility = View.GONE
        } else {
            params.height = originalHeight
            snapshotImageView.scaleType = ImageView.ScaleType.CENTER_INSIDE
            scaleFactor = 1.0f
            snapshotImageView.scaleX = 1.0f
            snapshotImageView.scaleY = 1.0f
            findViewById<ScrollView>(R.id.controlScrollView).visibility = View.VISIBLE
        }
        snapshotImageView.layoutParams = params
        showToastOnMainThread(if (isImageFullscreen) "进入全屏模式" else "退出全屏模式")
    }

    // 修改为 suspend 函数
    private suspend fun updateSnapshotImage(bitmap: android.graphics.Bitmap) {
        withContext(Dispatchers.Main) {
            snapshotImageView.setImageBitmap(bitmap)
            // 重置缩放状态
            scaleFactor = 1.0f
            snapshotImageView.scaleX = 1.0f
            snapshotImageView.scaleY = 1.0f
            if (isImageFullscreen) {
                toggleImageFullscreen() // 如果是全屏状态，恢复正常显示
            }
            showToast("截图接收完成！")
        }
    }

    private fun setupBiometricAuth() {
        val executor = ContextCompat.getMainExecutor(this)

        biometricPrompt = BiometricPrompt(this, executor,
            object : BiometricPrompt.AuthenticationCallback() {
                override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
                    super.onAuthenticationError(errorCode, errString)
                    if (errorCode == BiometricPrompt.ERROR_NO_BIOMETRICS) {
                        // 没有设置指纹
                        showToastOnMainThread("请先在系统设置中设置指纹")
                        startActivity(Intent(Settings.ACTION_SECURITY_SETTINGS))
                        finish()
                    } else {
                        showToastOnMainThread("认证错误: $errString")
                        finish()
                    }
                }

                override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
                    super.onAuthenticationSucceeded(result)
                    showToastOnMainThread("认证成功")
                    // 在认证成功后初始化UI
                    setContentView(R.layout.activity_main)
                    initializeViews()
                    initializeAdapter()
                    loadIpAddresses()
                    setupListeners()
                    setupImageInteraction()
                }

                override fun onAuthenticationFailed() {
                    super.onAuthenticationFailed()
                    showToastOnMainThread("认证失败，请重试")
                }
            })

        promptInfo = BiometricPrompt.PromptInfo.Builder()
            .setTitle("指纹验证")
            .setSubtitle("请验证指纹以继续使用")
            .setNegativeButtonText("取消")
            .build()
    }
}

@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
    Text(
        text = "Hello $name! I'm xxx",
        modifier = modifier
    )
}

@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
    MyControllerTheme {
        Greeting("Android")
    }
}
